package cn.hbads.support.structure;

import cn.hutool.core.collection.CollUtil;

import java.util.*;
import java.util.function.Function;

/**
 * <b> 常见结构工具类 </b>
 *
 * @author : yvvb
 * @since : 2025/5/20
 */
public final class StructUtil {
    private StructUtil() {
    }


    /**
     * <b>使用JDK8的Collectors.toMap若value为null会存在异常,因此用putIfAbsent自己造个轮子(注意规则是保留先插入的value)</b>
     *
     * @param originList {@link List} 原始数组
     *
     * @return {@link Map} HashMap映射
     */
    public static <K, V> Map<K, V> toMap(List<V> originList, Function<V, K> extraKeyFunction) {
        Map<K, V> resultMap = new HashMap<>();
        if (CollUtil.isEmpty(originList)) {
            return resultMap;
        }
        for (V origin : originList) {
            if (Objects.nonNull(origin)) {
                resultMap.putIfAbsent(extraKeyFunction.apply(origin), origin);
            }
        }
        return resultMap;
    }

    /**
     * <b>数组深拷贝</b>
     *
     * @param originList {@link List} 原始数组
     *
     * @return {@link List} 拷贝数组
     */
    public static <E extends cn.hbads.support.common.structure.trait.CopyTrait<E>> List<E> copyList(List<E> originList) {
        List<E> resultList = new ArrayList<>();
        if (CollUtil.isEmpty(originList)) {
            return resultList;
        }
        for (E origin : originList) {
            resultList.add(origin.copy());
        }
        return resultList;
    }

    /**
     * <b>安全地聚合有序数组</b>
     *
     * @param listArr {@link List[]} List的数组（动态）
     *
     * @return {@link List} 聚合后的List,ArrayList类型可修改
     */
    @SafeVarargs
    public static <E> List<E> safelyJoin(List<E>... listArr) {
        List<E> resultList = new ArrayList<>();
        if (Objects.isNull(listArr)) {
            return resultList;
        }
        for (List<E> list : listArr) {
            if (CollUtil.isNotEmpty(list)) {
                resultList.addAll(list);
            }
        }
        return resultList;
    }


    /**
     * <b>安全地转换并聚合有序数组</b>
     *
     * @param listArr {@link List[]} List的数组（动态）
     *
     * @return {@link List} 聚合后的List,ArrayList类型
     */
    @SafeVarargs
    public static <E, R> List<R> safelyMappingAndJoin(Function<E, R> mappingFunction, List<E>... listArr) {
        List<R> resultList = new ArrayList<>();
        if (Objects.isNull(listArr)) {
            return resultList;
        }
        for (List<E> list : listArr) {
            if (CollUtil.isNotEmpty(list)) {
                resultList.addAll(list.stream().map(mappingFunction).toList());
            }
        }
        return resultList;
    }

    /**
     * <b>安全地映射数组元素，【注意】处理过程会跳过源数组中空元素，因此不保证映射数组与传入数组元素数量一致</b>
     *
     * @param originList      {@link List} 传入数组
     * @param mappingFunction {@link Function} 映射关系
     *
     * @return {@link List} 返回数组
     */
    public static <E, R> List<R> filterNullMappingList(List<E> originList, Function<E, R> mappingFunction) {
        List<R> resultList = new ArrayList<>();
        if (CollUtil.isEmpty(originList)) {
            return resultList;
        }
        originList.forEach(e -> {
            if (Objects.nonNull(e)) {
                resultList.add(mappingFunction.apply(e));
            }
        });
        return resultList;
    }

}
